//package org.chs.ts.batch.job;
//
//
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//
//import lombok.extern.slf4j.Slf4j;
//import org.chs.ts.batch.controller.BatchExecController;
//import org.chs.ts.batch.log.entity.BatchClearBasicLog;
//import org.chs.ts.batch.service.IBatchClearBasicGroupInfoSetService;
//import org.chs.ts.batch.service.IBatchClearBasicLogService;
//import org.chs.ts.batch.set.entity.BatchClearBasicGroupInfoSet;
//import org.chs.ts.batch.util.CommonUtil;
//import org.chs.ts.batch.util.ParameterUtil;
//import org.chs.ts.base.batch.vo.entity.BatchExecResp;
//import org.chs.ts.main.common.exception.ServiceException;
//import org.chs.ts.main.common.util.RedissonLockService;
//import org.chs.ts.main.common.util.oConvertUtils;
//import org.chs.ts.vo.batch.Result;
//import org.springframework.core.env.Environment;
//import org.springframework.scheduling.annotation.EnableScheduling;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//import java.text.SimpleDateFormat;
//import java.util.List;
//import java.util.Locale;
//
///**
// * @Compay 盛唐天行
// * @Author: wuwei
// * @Censor By wuwei
// * @Sence 2023/5/29 11:15
// * @Modify 2023/5/29 11:15
// * @Description 守护进程 针对跑批组进行扫描监控(需要参数配置：isOpenDeamon)
// */
//@EnableScheduling
//@Component
//@Slf4j
//public class BatchTaskDeamonScheduled {
//    @Resource
//    private RedissonLockService redissonLockService;
//    @Resource
//    private BatchExecController batchExecController;
//    @Resource
//    private ParameterUtil parameterUtil;
//    @Resource
//    private Environment environment;
//    @Resource
//    private IBatchClearBasicGroupInfoSetService clearBasicGroupInfoService;
//    @Resource
//    private IBatchClearBasicLogService clearBasicLogService;
//
//    //    private String taskId;
//    private List<BatchClearBasicGroupInfoSet> taskGroupList;
//    private String batchSysCode;
//
//    private String taskGroup;
//    private String execDate;
//    private String snatchingMode;
//    //private String coreDay;
//
//    private final int MAX_ERROR_COUNT = 5;
//    private final long MAX_WAITTING_TIME = 5000;
//
//    // 每小时 00分05秒 30分05秒 执行
//    //@Scheduled(cron = "15 15 08 * * ?")
//    //@CacheLock(expireTime = 60,lockedKey="BatchTaskDeamonScheduled")
//    //@Scheduled(cron = "50 * * * * ?")
//    public void process() {
//        String key = "BatchTaskDeamonScheduled" + new SimpleDateFormat("HHmmss").format(new Date());
//        redissonLockService.dealLockAndUnlock(key, () -> {
//            //参数配置 是否 执行
//            if (!Boolean.parseBoolean(parameterUtil.getParameterByCode("isOpenDeamon"))) {
//                log.info("BatchTaskDeamonScheduled 未开启" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//                return;
//            }
//            String logSernoPrdfix = "BatchTaskDeamon";
//
//            // 限制只执行一次
//            if (checkTodayIsFinish(logSernoPrdfix)) {
//                log.info("BatchTaskDeamonScheduled:后台跑批守护线程,当日已执行无法重复执行！" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//                createClearBasicLog(false, "后台跑批守护线程,当日已执行无法重复执行!" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), "");
//                return;
//            }
//
//            log.info("BatchTaskDeamonScheduled 后台跑批守护线程开始执行！" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//
//            // 获取 待执行 列表
//            initParameter();
//            //batchExecController.getTaskWaittingList();
//            for (BatchClearBasicGroupInfoSet taskGroup : this.taskGroupList) {
//                // 验证 是否 存在 待执行列表
//                boolean isGetWaitting = batchExecController.checkTaskWaittingValue(taskGroup.getBatchSysCode(), taskGroup.getTaskGroup(),
//                        this.execDate);
//
//                if (isGetWaitting) {
////                this.taskGroup = taskWaittingList.getTaskGroup();
////                this.snatchingMode = taskWaittingList.getSnatchingMode();
//                    log.info("BatchTaskDeamonScheduled 后台跑批守护线程-存在跑批组未执行！ taskGroup -> [" + taskGroup.getTaskGroup() + "] execDate -> [" + this.execDate + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//                    createClearBasicLog(true, "BatchTaskDeamonScheduled 后台跑批守护线程-存在跑批组未执行！ taskGroup -> [" + taskGroup.getTaskGroup() + "] execDate" +
//                            " -> [" + this.execDate + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), "");
//                    this.taskGroup = taskGroup.getTaskGroup();
//                    this.batchSysCode = taskGroup.getBatchSysCode();
//                    String finalTaskGroup = this.taskGroup;
//                    String finalExecDate = this.execDate;
//                    String finalSnatchingMode = this.snatchingMode;
//                    String finalBatchSysCode = this.batchSysCode;
//                    Thread taskThread = new Thread(() -> batchTaskRunning(finalBatchSysCode, finalTaskGroup, finalExecDate, finalSnatchingMode));
//                    taskThread.start();
//
//                }
//
//
//            }
//            log.info("BatchTaskDeamonScheduled 后台跑批守护线程执行结束!" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//        }, new ServiceException(RetCode.FAILED, "未能获取锁，等待下次重新获取"));
//
//    }
//
//    private void batchTaskRunning(String batchSysCode, String taskGroup, String execDate, String snatchingMode) {
//        // 获取 当前待执行 taskGroup 信息 准备后续 进行执行
//        log.info("BatchTaskDeamonScheduled 后台跑批守护线程执行日志 taskGroup -> [" + taskGroup + "] execDate -> [" + execDate + "] snatchingMode -> [" + snatchingMode + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//        createClearBasicLog(true, "BatchTaskDeamonScheduled 后台跑批守护线程执行日志 taskGroup -> [" + taskGroup + "] execDate -> [" + execDate + "] " +
//                "snatchingMode -> [" + snatchingMode + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), "");
//        boolean runningStatus = startTaskRunningStatus(batchSysCode, taskGroup, this.execDate);
//        if (!runningStatus) {
//            createClearBasicLog(false, "BatchTaskDeamonScheduled 执行日志-开启跑批状态失败 taskGroup -> [" + taskGroup + "] execDate -> [" + execDate + "] " +
//                    "snatchingMode -> [" + snatchingMode + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), "");
//            return;
//        }
//        int i = 0;
//        while (i < MAX_ERROR_COUNT) {
//            //log.info("BatchTaskScheduled 执行日志:跑批定时任务!获取跑批任务 taskGroup[" + this.taskGroup + "] execDate[" + this.execDate + "] snatchingMode[" +
//            // this.snatchingMode + "] " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//            Result<BatchExecResp> task = batchExecController.getTask(batchSysCode, taskGroup, execDate, snatchingMode);
//            if (task.getResult().getRtnCode().equals("000000")) {
//                // 获取 待执行记录 进行执行
//                //log.info("BatchTaskScheduled 执行日志:跑批定时任务!执行跑批任务 taskGroup[" + this.taskGroup + "] execDate[" + this.execDate + "] snatchingMode["
//                // + this.snatchingMode + "] taskExecId[" + task.getResult().getTaskExecId() + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
//                // .format(new Date()));
//
//                try {
//                    batchExecController.process(task.getResult().getTaskExecId(), snatchingMode);
//                    createClearBasicLog(false,
//                            "BatchTaskDeamonScheduled 执行日志:跑批定时任务!任务编号" + task.getResult().getTaskExecId() + "运行" + new SimpleDateFormat("yyyy-MM" +
//                                    "-dd HH:mm:ss").format(new Date()), execDate);
//
//                } catch (Exception e) {
//                    // e.printStackTrace();
//                    createClearBasicLog(false,
//                            "BatchTaskDeamonScheduled 执行日志:跑批定时任务!任务编号" + task.getResult().getTaskExecId() + "异常" + e.getMessage() + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), execDate);
//
//                }
//                try {
//                    Thread.sleep(MAX_WAITTING_TIME);
//                } catch (InterruptedException e) {
//                    //e.printStackTrace();
//                }
//                // 计数器清零
//                i = 0;
//            }
//
//            if (task.getResult().getRtnCode().equals("999999")) {
//                //log.info("BatchTaskScheduled 执行日志:跑批定时任务!第" + (i + 1) + "次抢夺跑批任务失败 taskGroup[" + this.taskGroup + "] execDate[" + this.execDate +
//                // "] snatchingMode[" + this.snatchingMode + "] taskExecId[" + task.getResult().getTaskExecId() + "]" + new SimpleDateFormat
//                // ("yyyy-MM-dd HH:mm:ss").format(new Date()));
//
//                // 未获取 待执行任务 进行幂等 稍后调用
//                try {
//                    Thread.sleep((long) Math.pow(2, i++ / 5) * MAX_WAITTING_TIME);
//                } catch (InterruptedException e) {
//                    //e.printStackTrace();
//                }
//                continue;
//            }
//
//            if (task.getResult().getRtnCode().equals("111111")) {
//                //log.info("BatchTaskScheduled 执行日志:跑批定时任务!执行跑批任务完成 taskGroup[" + taskGroup + "] execDate[" + execDate + "] snatchingMode[" +
//                // snatchingMode + "] taskExecId[" + task.getResult().getTaskExecId() + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format
//                // (new Date()));
//                // 关闭 跑批任务
//                boolean stopRunningStatus = stopTaskRunningStatus(batchSysCode, taskGroup, execDate);
//                if (!stopRunningStatus) {
//                    createClearBasicLog(false,
//                            "BatchTaskDeamonScheduled 执行日志-关闭跑批状态失败 taskGroup -> [" + taskGroup + "] execDate -> [" + execDate + "] snatchingMode " +
//                                    "-> [" + snatchingMode + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), "");
//                    return;
//                }
//
//                // 执行列表结束 跳出循环
//                break;
//            }
//        }
//    }
//
//    private boolean stopTaskRunningStatus(String batchSysCode, String taskGroup, String execDate) {
//        Boolean taskRunningStatus = batchExecController.getTaskRunningStatus(batchSysCode, taskGroup, execDate, this.snatchingMode);
//        if (taskRunningStatus) {
//            for (int i = 0; i < MAX_ERROR_COUNT; i++) {
//                log.info("BatchTaskDeamonScheduled 执行日志-第[" + (i + 1) + "]次开启跑批状态 taskGroup -> [" + this.taskGroup + "] execDate -> [" + this.execDate + "] snatchingMode -> [" + this.snatchingMode + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//                taskRunningStatus = batchExecController.stopTaskRunningStatus(batchSysCode, taskGroup, execDate, this.snatchingMode);
//                // 开启成功 终止当前循环
//                if (taskRunningStatus) {
//                    break;
//                }
//                // 开启失败 暂停5000毫秒
//                try {
//                    Thread.sleep(MAX_WAITTING_TIME);
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//        }
//        return taskRunningStatus;
//    }
//
//    /**
//     * 开启 跑批状态 如开启失败 将进行多次开启
//     *
//     * @param taskGroup 跑批过程组
//     * @param execDate  跑批执行时间
//     * @return 开启指定跑批执行时间 跑批过程组 状态
//     */
//    private boolean startTaskRunningStatus(String batchSysCode, String taskGroup, String execDate) {
//        Boolean taskRunningStatus = batchExecController.getTaskRunningStatus(batchSysCode, taskGroup, execDate, this.snatchingMode);
//        if (!taskRunningStatus) {
//            for (int i = 0; i < MAX_ERROR_COUNT; i++) {
//                log.info("BatchTaskDeamonScheduled 执行日志-第[" + (i + 1) + "]次开启跑批状态 taskGroup -> [" + this.taskGroup + "] execDate -> [" + this.execDate + "] snatchingMode -> [" + this.snatchingMode + "]" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//                taskRunningStatus = batchExecController.startTaskRunningStatus(batchSysCode, taskGroup, execDate, this.snatchingMode);
//                // 开启成功 终止当前循环
//                if (taskRunningStatus) {
//                    break;
//                }
//                // 开启失败 暂停5000毫秒
//                try {
//                    Thread.sleep(MAX_WAITTING_TIME);
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//        }
//        return taskRunningStatus;
//    }
//
//    /**
//     * 验证当前时间 是否可执行跑批操作
//     *
//     * @param cut_time 系统参数 日切时间
//     * @return boolean
//     * @Description 先解析小时，确认小时是否符合
//     */
////
//
//    /**
//     * 获取 系统参数 预更新时间方法
//     *
//     * @return 指定时间类型 待更新日期
//     */
//    //private String getDayByParameter(String corDay, int diffDate) {
//    //    Date date = null;
//    //    try {
//    //        date = (new SimpleDateFormat("yyyyMMdd")).parse(corDay);
//    //    } catch (ParseException e) {
//    //        date = new Date();
//    //        log.error("BatchTaskScheduled -> getDayByParameter 日期转换 异常！入参[后管平台]->[核心日期]： " + corDay);
//    //        e.printStackTrace();
//    //    }
//    //    GregorianCalendar calendar = new GregorianCalendar();
//    //    calendar.setTime(date);
//    //    calendar.add(java.util.Calendar.DATE, diffDate);
//    //    return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
//    //}
//
//    /**
//     * 初始化参数
//     */
//    private void initParameter() {
//        this.execDate = parameterUtil.getParameterByCode(ParamConstant.LAST_DAY);
//        //this.coreDay = parameterUtil.getParameterByCode(ParamConstant.CORE_DAY);
//        this.taskGroup = "";
//        this.snatchingMode = "redis";
//        this.taskGroupList = clearBasicGroupInfoService.getAvailabilityGroupInfo();
//
//    }
//
////    private String getGroupInfoParameter(String taskGroup, String preTaskParameter, String key) {
////        String logSernoPrdfix = "groupInfoParameter";
////        String returnValue = "";
////        if (Strings.isBlank(preTaskParameter) || preTaskParameter.equals("{}")) {
////            createClearBasicLog(false, "获取跑批组参数为空! taskGroup -> " + taskGroup + " preTaskParameter -> " + preTaskParameter, "", logSernoPrdfix);
////            log.info("getGroupInfoParameter:获取跑批组参数异常  获取跑批组参数为空! taskGroup -> " + taskGroup + " preTaskParameter -> " + preTaskParameter + new
////            SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
////        } else {
////            try {
////                JSONObject parameter = JSONObject.parseObject(preTaskParameter);
////                if (parameter.containsValue(key)) {
////                    createClearBasicLog(false, "获取跑批组参数key不存在! taskGroup -> " + taskGroup + " preTaskParameter -> " + preTaskParameter + " key ->
////                    " + key, "", logSernoPrdfix);
////                    log.info("getGroupInfoParameter:获取跑批组参数异常  获取跑批组参数key不存在! taskGroup -> " + taskGroup + " preTaskParameter -> " +
////                    preTaskParameter + " key -> " + key + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
////                }
////                returnValue = parameter.getString(key);
////            } catch (JSONException e) {
////                createClearBasicLog(false, "获取跑批组参数异常! taskGroup -> " + taskGroup + " preTaskParameter -> " + preTaskParameter + " " + e
////                .getMessage(), "", logSernoPrdfix);
////                log.info("getGroupInfoParameter:获取跑批组参数异常  获取跑批组参数异常! taskGroup -> " + taskGroup + " preTaskParameter -> " + preTaskParameter + "
////                " + e.getMessage() + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
////            }
////        }
////        return returnValue;
////    }
//
//    private void createClearBasicLog(boolean runningResult, String errMsg, String currentDate, String logSernoPrdfix) {
//        if (logSernoPrdfix.length() > 19) {
//            logSernoPrdfix = logSernoPrdfix.substring(0, 19);
//            log.error("createClearBasicLog -> logSernoPrdfix参数过长请及时调整，参数长度应小于等于1位： " + logSernoPrdfix + "[" + logSernoPrdfix.length() + "]");
//        }
//        currentDate = currentDate.equals("") ? new SimpleDateFormat("yyyyMMdd").format(new Date()) : currentDate;
//        String ip = CommonUtil.getLocalHostAddress();
////        try {
////            ip = InetAddress.getLocalHost().getHostName();
////        } catch (UnknownHostException e) {
////            e.printStackTrace();
////
////        }
//        String port = environment.getProperty("server.port");
//        String path = oConvertUtils.getString(environment.getProperty("server.servlet.context-path"));
//
//        BatchClearBasicLog clearBasicLog = new BatchClearBasicLog();
//        clearBasicLog.setSysOrgCode("");//所属部门
//        clearBasicLog.setLogSerno(logSernoPrdfix.toUpperCase(Locale.ROOT) + System.currentTimeMillis());//日志号
//        clearBasicLog.setTaskDate(currentDate);//清算业务日期
//        clearBasicLog.setExecStatus(runningResult ? "3" : "4");//执行状态 (0-未执行; 1-占用中; 2-执行中;   3-执行成功; 4-执行失败; 5-跳过执行; 6-任务终止; )
//        clearBasicLog.setExecDate(currentDate);//执行日期
//        clearBasicLog.setShouldExecDate(currentDate);//应执行日期
//        clearBasicLog.setServerName(path);//服务器主机名
//        clearBasicLog.setServerIp(ip + ":" + port);//服务器IP
//        clearBasicLog.setRtnCode(runningResult ? RetCode.SUCCESS : RetCode.FAILED);//返回码
//        clearBasicLog.setRtnDesc(errMsg);//执行结束信息
//
//        clearBasicLogService.save(clearBasicLog);
//
//    }
//
//    private void createClearBasicLog(boolean runningResult, String errMsg, String currentDate) {
//        String logSernoPrdfix = "BatchTaskDeamon";
//        createClearBasicLog(runningResult, errMsg, currentDate, logSernoPrdfix);
//    }
//
//    /**
//     * 确认 当前 是否执行
//     */
//    private boolean checkTodayIsFinish(String logSernoPrdfix) {
//        logSernoPrdfix += "%";
//        String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
//        String rtnCode = RetCode.SUCCESS;
//        long count = clearBasicLogService.count(
//                new LambdaQueryWrapper<BatchClearBasicLog>().eq(BatchClearBasicLog::getExecDate, currentDate)
//                        .eq(BatchClearBasicLog::getRtnCode, rtnCode).like(BatchClearBasicLog::getLogSerno, logSernoPrdfix));
//        return count > 0;
//    }
//}
